package com.itfreer.ui.form;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.itfreer.core.file.FileMeta;
import com.itfreer.core.file.Utils;
import com.itfreer.core.file.path.FileService;
import com.itfreer.core.file.path.FileUpload;
import com.itfreer.ui.R;
import com.itfreer.ui.audio.player.PlayerView;
import com.itfreer.ui.audio.recoder.AudioRecoderUtils;
import com.itfreer.ui.audio.recoder.RecoderButton;
import com.itfreer.ui.base.api.IEditTextValidator;
import com.itfreer.ui.base.api.IPower;
import com.itfreer.ui.base.api.ISimpleView;
import com.itfreer.utils.PixelUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * 定义语音录制与播发控件
 */
public class AudioView extends LinearLayout implements ISimpleView, IEditTextValidator, IPower {

    private String fieldName;
    private boolean readonly = false;
    private boolean required = false;
    private String validateTitle = "";
    private String validateName = "";
    private TextView title;

    private RecoderButton recoderButton;
    private PlayerView playerView;
    private FileMeta fileMeta;

    public AudioView(Context context) {
        super(context);
        setView(context);
    }

    public AudioView(Context context, AttributeSet attrs){
        super(context, attrs);
        getAttrs(context, attrs);
        setView(context);
    }

    public AudioView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        getAttrs(context, attrs);
        setView(context);
    }

    protected void getAttrs(Context context, AttributeSet attrs){
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SimpleView);
        this.fieldName = a.getString(R.styleable.SimpleView_fieldName);
        this.readonly = a.getBoolean(R.styleable.SimpleView_readonly, false);
        this.validateTitle = a.getString(R.styleable.SimpleView_validateTitle);
        this.validateName = a.getString(R.styleable.SimpleView_validatorName);
        this.required = a.getBoolean(R.styleable.SimpleView_required, false);
    }

    /**
     * 设置当前的视图
     * @param context
     */
    protected void setView(Context context){
        this.setBackgroundColor(Color.WHITE);
        this.setGravity(Gravity.CENTER_VERTICAL);
        this.setOrientation(VERTICAL);
        this.setPadding(0, PixelUtils.dpToPx(context, 8), 0, PixelUtils.dpToPx(context, 8));

        title = new TextView(context);
        LayoutParams titleParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        titleParams.setMarginStart(PixelUtils.dpToPx(context, 18));
        title.setLayoutParams(titleParams);
        title.setText(this.validateTitle);
        title.setTextColor(Color.BLACK);
        title.setTextSize(PixelUtils.dpToPx(getContext(), 6));
        this.addView(title);

        recoderButton = new RecoderButton(context);
        LayoutParams recoderParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        recoderParams.gravity = Gravity.RIGHT;
        recoderParams.rightMargin = PixelUtils.dpToPx(context, 15);
        recoderParams.bottomMargin = PixelUtils.dpToPx(context, 15);
        recoderParams.topMargin = PixelUtils.dpToPx(context, 8);
        recoderButton.setLayoutParams(recoderParams);
        this.addView(recoderButton);
        recoderButton.init(this);
        recoderButton.setListener(new AudioRecoderUtils.OnAudioStatusUpdateListener() {
            @Override
            public void onUpdate(double db, long time) {

            }

            @Override
            public void onStop(String filePath) {
                fileMeta = saveFile(filePath);
                setState();
            }
        });

        playerView = new PlayerView(context);
        LayoutParams playerParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        playerView.setLayoutParams(playerParams);
        playerView.setValidateTitle(this.validateTitle + "录音");
        this.addView(playerView);
        playerView.setDelClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                fileMeta = null;
                setState();
            }
        });
    }

    public void setReadonly(boolean readonly) {
        recoderButton.setVisibility(GONE);
        playerView.setVisibility(VISIBLE);
        playerView.setReadonly(readonly);
    }

    public void setRequired(boolean required) {
        this.required = required;
    }

    @Override
    public String getSecurityID() {
        return "";
    }

    @Override
    public void setSecurityVisible(boolean visible) {

    }

    @Override
    public void setFieldName(String name) {
        this.fieldName = name;
    }

    @Override
    public String getFieldName() {
        return this.fieldName;
    }

    @Override
    public void setFieldValue(Object value) {
        FileMeta[] fileMetas = null;
        if (value != null) {// 获取绑定字段中的图片传输到上传控件做展示使用
            // 获取绑定字段中的图片传输到上传控件做展示使用
            fileMetas = Utils.getFileMeta(value.toString());
        }
        if(fileMetas == null || fileMetas.length<=0) {
            fileMeta = null;
        } else {
            fileMeta = fileMetas[0];
        }
        setState();
    }

    private void setState() {
        if(fileMeta == null) {
            recoderButton.setVisibility(VISIBLE);
            playerView.setVisibility(GONE);
        } else {
            recoderButton.setVisibility(GONE);
            playerView.setVisibility(VISIBLE);

            player();
        }
    }

    private void player() {
        String objectKey = fileMeta.getKey();
        String file = FileService.instance.getFile("plupload", objectKey);
        playerView.start(file);
    }

    @Override
    public Object getFieldValue() {
        FileMeta[] fms = new FileMeta[1];
        fms[0] = fileMeta;
        String jsonString = Utils.getFileString(fms);
        return jsonString;
    }

    @Override
    public String getValidatorName() {
        return this.validateName;
    }

    @Override
    public void setValidatorName(String name) {
       this.validateName = name;
    }

    @Override
    public String getValidateTitle() {
        return this.validateTitle;
    }

    @Override
    public void setValidateTitle(String validateTitle) {
        this.validateTitle = validateTitle;
        playerView.setValidateTitle(validateTitle + "录音");
        title.setText(this.validateTitle);
    }

    private FileMeta saveFile(String path) {
        if(path.startsWith("/raw/")){
            path = path.substring(5);
        }
        byte[] content = getImageStream(path);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String ymd = sdf.format(new Date());
        String[] files = path.split("\\.");
        String objectKey = ymd + "/" + UUID.randomUUID().toString().replace("-", "") + "." + files[files.length-1];
        FileUpload.instance.putObject("plupload", objectKey, content);

        FileMeta fileMeta = new FileMeta();
        fileMeta.setBucketName("plupload");
        fileMeta.setKey(objectKey);
        return fileMeta;
    }

    private static byte[] getImageStream(String path) {
        byte[] buffer = null;
        File file = new File(path);
        FileInputStream fis;
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    public void stop() {
        playerView.stop();
    }
}
